﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;

namespace IN.Util
{
    /// <summary>
    /// 序列化和反序列化
    /// </summary>
    /// <typeparam name="T">要进行序列化的类型</typeparam>
    public class SerializeClass<T> where T : new()
    {

        /// <summary>
        /// 二进制序列化
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="obj"></param>
        public void Serialize(string path, string fileName, T obj)
        {
            string errstr = "";
            string fileFullName = path + "\\" + fileName;

            ExitsFile(path, fileName, out errstr);

            FileStream fileStream = new FileStream(fileFullName, FileMode.Create);
            BinaryFormatter b = new BinaryFormatter();
            //SoapFormatter b = new SoapFormatter();

            b.Serialize(fileStream, obj);
            fileStream.Close();
        }



        /// <summary>
        /// 二进制反序列化
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public T DeSerialize(string fileName)
        {
            T obj = new T();

            if (File.Exists(fileName) == false) return obj;

            FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
            BinaryFormatter b = new BinaryFormatter();
            //SoapFormatter b = new SoapFormatter();

            obj = (T)b.Deserialize(fileStream);

            fileStream.Close();

            return obj;
        }




        /// <summary>
        /// XML序列化：将实体对象转化为XML文件
        /// </summary>
        /// <param name="path"></param>
        /// <param name="fileName"></param>
        /// <param name="obj"></param>
        public void SerializeXML(string path, string fileName, T obj, out string errstr)
        {
            errstr = "";
            string fileFullName = path + "\\" + fileName;
            ExitsFile(path, fileName, out errstr);


            XmlDocument xd = new XmlDocument();
            using (StringWriter sw = new StringWriter())
            {
                XmlSerializer xz = new XmlSerializer(obj.GetType());
                xz.Serialize(sw, obj);
                Console.WriteLine(sw.ToString());
                xd.LoadXml(sw.ToString());
                xd.Save(fileFullName);
            }
        }

        /// <summary>
        /// XML反序列化：将XML文件转化为实体对象
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public T DeSerializeXML(string path, string fileName, out string err)
        {


            err = "";

            ExitsFile(path, fileName, out err);
            T obj = new T();

            //如果文件大小为0，则序列化一个空文件
            if (GetFileSize(path + "\\" + fileName) == 0)
            {
                SerializeXML(path, fileName, obj, out err);
            }


            try
            {

                using (XmlReader reader = XmlReader.Create(path + "\\" + fileName))
                {
                    XmlSerializer xz = new XmlSerializer(obj.GetType());

                    obj = (T)xz.Deserialize(reader);
                    Console.WriteLine(reader.ToString());
                }
            }
            catch (Exception ex)
            {

                err = ex.ToString();
            }
            return obj;
        }




        /// <summary>
        /// 检查路径和文件是否存在，并创建
        /// </summary>
        /// <param name="path"></param>
        /// <param name="fileName"></param>
        private void ExitsFile(string path, string fileName, out string err)
        {
            err = "";

            try
            {

                string fileFullName = path + "\\" + fileName;

                if (Directory.Exists(path) == false) Directory.CreateDirectory(path);

                if (File.Exists(fileFullName) == false)
                {
                    FileStream fs = File.Create(fileFullName);
                    fs.Close();
                }
            }
            catch (Exception ex)
            {
                err = ex.ToString();
            }
        }


        public long GetFileSize(string FilePath)
        {
            //获取文件大小，以判断生成的文件是否有效
            long m_Size = 0;
            FileInfo fi = new FileInfo(FilePath);
            try
            {
                m_Size = fi.Length;
            }
            catch
            {
                m_Size = 0;
            }
            return m_Size;
        }

    }
}
